/*
@auther fenglei
*/
package xxlog

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"github.com/getsentry/sentry-go"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
)

type LogOptions struct {
	LogName    string
	MaxSize    int
	MaxBackups int
	MaxAge     int
	SentryDNS  string
	LogPrint   bool
}

func NewInitZapLog(opts *LogOptions) error {
	logs, err := zapLog(opts)
	if err != nil {
		return err
	}
	XXLog_Logger = logs
	return nil
}
func zapLog(opts *LogOptions) (*zap.Logger, error) {
	// 配置日志输出
	opts = setLogsDefaults(opts)
	logDir := getLogDir(opts.LogName)
	fmt.Println("logDir:", logDir)
	w := zapcore.AddSync(&lumberjack.Logger{
		Filename:   logDir,          // 日志文件路径
		MaxSize:    opts.MaxSize,    // 每个日志文件保存的最大尺寸 单位：M
		MaxBackups: opts.MaxBackups, // 最多保留5个备份文件
		MaxAge:     opts.MaxAge,     // 文件最多保存多少天
		Compress:   true,            // 是否压缩
	})
	// 创建一个默认的 encoder 配置
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.TimeKey = "timestamp"
	// 指定时间序列化函数，将时间序列化为 `2006-01-02 15:04:05.000` 格式，更易读
	encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
		enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
	}
	// 指定 time.Duration 序列化函数，将 time.Duration 序列化为经过的毫秒数的浮点数
	// 毫秒数比默认的秒数更精确
	encoderConfig.EncodeDuration = func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
		enc.AppendFloat64(float64(d) / float64(time.Millisecond))
	}
	//encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	// 移除caller字段
	encoderConfig.CallerKey = ""
	encoder := zapcore.NewJSONEncoder(encoderConfig)
	// 创建核心
	core := zapcore.NewCore(encoder, w, zapcore.InfoLevel)
	// 创建logger
	//logger := zap.New(core, zap.AddCaller())
	if opts.SentryDNS != "" {
		// 初始化sentry
		if err := sentryInit(opts.SentryDNS); err != nil {
			return nil, err
		}
	}
	return zap.New(core), nil
}
func getLogDir(name string) string {
	// Darwin (macOS) 环境
	if strings.TrimSpace(runtime.GOOS) == "darwin" {
		return fmt.Sprintf("/Users/fenglei/WorkGo/logs/%s", name)
	}
	// 非 Darwin 环境，使用当前运行目录
	currentDir, err := os.Getwd()
	if err != nil {
		// 如果获取当前目录失败，使用可执行文件所在目录
		if execPath, err := os.Executable(); err == nil {
			currentDir = filepath.Dir(execPath)
		} else {
			// 最后的后备方案，使用空字符串让系统自动使用当前目录
			currentDir = ""
		}
	}
	// 确保 logs 目录存在
	logsDir := filepath.Join(currentDir, "logs")
	return filepath.Join(logsDir, name)
}
func sentryInit(dns string) error {
	if strings.TrimSpace(dns) != "" {
		err := sentry.Init(sentry.ClientOptions{
			Dsn: dns,
		})
		if err != nil {
			return err
		}
	}
	return nil
}
func setLogsDefaults(opts *LogOptions) *LogOptions {
	if opts.MaxSize == 0 {
		opts.MaxSize = 100
	}
	if opts.MaxBackups == 0 {
		opts.MaxBackups = 5
	}
	if opts.MaxAge == 0 {
		opts.MaxAge = 30
	}
	if opts.LogName == "" {
		opts.LogName = "test.log"
	}
	if opts.LogPrint {
		is_print = true
	}
	return opts
}
